package com.darren.archive.service.impl;

import com.darren.archive.dao.SysFunctionDao;
import com.darren.archive.entity.SysFunction;
import com.darren.archive.entity.SysUser;
import com.darren.archive.service.SysFunctionService;
import com.darren.framework.service.impl.GenericServiceImpl;
import com.darren.framework.shiro.ShiroUtil;
import com.darren.framework.utils.Constant;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <pre>
 * *********************************************
 * Copyright DARREN
 * All rights reserved.
 * Description: TODO(description)
 * HISTORY:
 * *********************************************
 *  Version		Date		Author	   		Desc
 *   v1.0       2018-04-11  Darren Zhou    Create
 *
 * *********************************************
 * </pre>
 */

@Service
public class SysFunctionServiceImpl extends GenericServiceImpl<SysFunction, Long> implements SysFunctionService {

    @Resource
    private SysFunctionDao sysFunctionDao;


    @Override
    public List<SysFunction> getFunctionTree() {
        SysUser sysUser = ShiroUtil.getSysUser();
        List<SysFunction> sysFunctions = new ArrayList<SysFunction>();
        if (sysUser == null || !sysUser.isEditable()) {
            sysFunctions = sysFunctionDao.getAllEnableFunction();
        } else {
            sysFunctions = getEnableSysFunctionByUserId(sysUser.getId());
        }
        return constructFunctionTree(sysFunctions, 0L);
    }

    @Override
    @Cacheable(value = Constant.CACHE_SYS_FUNCTIONS, key = "T(String).valueOf(#functionName).concat('-').concat('functionNameLike')")
    public List<SysFunction> getFunctionList(String functionName) {
        List<SysFunction> sysFunctions = sysFunctionDao.getAllByFunctionName(functionName);
        if (sysFunctions == null || sysFunctions.size() == 0) {
            return new ArrayList<SysFunction>();
        }
        return constructFunctionTree(sysFunctions, 0L);
    }

    /**
     * 递归构造功能树结构
     *
     * @param functionList
     * @param parentId
     * @return
     */
    private List<SysFunction> constructFunctionTree(List<SysFunction> functionList, Long parentId) {
        List<SysFunction> treeFunctions = functionList.stream().filter(item -> item.getParentId().equals(parentId)).collect(Collectors.toList());
        treeFunctions.sort((SysFunction fun1, SysFunction fun2) -> fun1.getDisplaySequence().compareTo(fun2.getDisplaySequence()));
        for (SysFunction sysFunction : treeFunctions) {
            sysFunction.setChildren(constructFunctionTree(functionList, sysFunction.getId()));
        }
        return treeFunctions;
    }


    @Override
    @Cacheable(value = Constant.CACHE_SYS_FUNCTIONS, key = "all")
    public List<SysFunction> getAllFunctions() {
        return sysFunctionDao.getAll();
    }

    @Override
    @CacheEvict(value = Constant.CACHE_SYS_FUNCTIONS, allEntries = true)
    public SysFunction save(SysFunction entity) {
        return sysFunctionDao.merge(entity);
    }

    @Override
    @CacheEvict(value = Constant.CACHE_SYS_FUNCTIONS, allEntries = true)
    public SysFunction update(SysFunction entity) {
        return sysFunctionDao.update(entity);
    }

    @Override
    @CacheEvict(value = Constant.CACHE_SYS_FUNCTIONS, allEntries = true)
    public void delete(SysFunction entity) {
        sysFunctionDao.delete(entity);
    }

    @Override
    @CacheEvict(value = Constant.CACHE_SYS_FUNCTIONS, allEntries = true)
    public void deleteById(Long id) {
        sysFunctionDao.deleteById(id);
    }

    @Override
    @Cacheable(value = Constant.CACHE_SYS_FUNCTIONS, key = "#id")
    public SysFunction findById(Long id) {
        return sysFunctionDao.findById(id);
    }

    /**
     * 根据用户id，获取其所拥有的功能列表
     *
     * @param userId
     * @return
     */
    @Override
    @Cacheable(value = Constant.CACHE_SYS_FUNCTIONS, key = "T(String).valueOf(#userId).concat('-').concat('useid')")
    public List<SysFunction> getEnableSysFunctionByUserId(Long userId) {
        return sysFunctionDao.getEnableSysFunctionByUserId(userId);
    }

    @Override
    @CacheEvict(value = Constant.CACHE_SYS_FUNCTIONS, allEntries = true)
    public SysFunction saveEnable(SysFunction record) {
        SysFunction sysFunction = sysFunctionDao.findById(record.getId());
        sysFunction.setEnable(record.isEnable());
        return sysFunctionDao.save(sysFunction);
    }
}
